package com.ayz.gateway.center.domain.service.remoting;

import cn.hutool.core.util.StrUtil;

import com.ayz.gateway.api.request.ApplicationConfig;
import com.ayz.gateway.api.server.RegistryApplicationServerGrpc;
import com.ayz.gateway.center.domain.repository.IApiRepository;
import com.ayz.gateway.common.constants.ApiData;
import com.ayz.gateway.common.constants.ApplicationConfigWrapper;
import com.ayz.gateway.common.constants.DataVersion;
import com.ayz.gateway.common.constants.MethodData;
import com.ayz.gateway.server.grpc.GrpcServerConstants;
import com.google.protobuf.Empty;
import io.grpc.stub.StreamObserver;
import lombok.Data;

import java.util.List;

/**
 * @ClassName RegistryApplicationServiceImpl
 * @Description TODO: 应用程序API注册到网关注册中心的实现类
 * @Author 快乐的星球
 * @Date 2023/5/23 20:28
 * @Version 1.0
 **/
@Data
public class RegistryApplicationServiceImpl extends RegistryApplicationServerGrpc.RegistryApplicationServerImplBase {
    private IApiRepository apiRepository;

    public RegistryApplicationServiceImpl(IApiRepository apiRepository) {
        this.apiRepository = apiRepository;
    }

    @Override
    public void registerApplication(RegistryApplication.RegistryApplicationRequest request, StreamObserver<Empty> responseObserver) {
        //1:获取客户端的地址
        String clientIp = GrpcServerConstants.CONTEXT_KEY_CONN_REMOTE_IP.get();
        Integer port = GrpcServerConstants.CONTEXT_KEY_CONN_REMOTE_PORT.get();
        String address = clientIp+":"+port;
        String applicationName = request.getApplicationName();
        String gatewayGroup = request.getGatewayGroup();
        ApplicationConfig.ApplicationConfigWrapper applicationConfigWrapper = request.getApplicationConfigWrapper();
        ApplicationConfigWrapper configWrapper = buildApplicationConfigWrapper(applicationName, applicationConfigWrapper);
        if(StrUtil.isNotBlank(applicationName) && StrUtil.isNotBlank(gatewayGroup)){
            /**
             * 将API信息存储到本地内存存储中心
             */
            apiRepository.registerApplication(address,applicationName,configWrapper,gatewayGroup);
        }
        responseObserver.onNext(Empty.newBuilder().build());
        responseObserver.onCompleted();
    }
    /**
     * 构建 ApplicationConfigWrapper对象
     * @param applicationConfigWrapper
     * @return
     */
    private ApplicationConfigWrapper buildApplicationConfigWrapper(String applicationName,ApplicationConfig.ApplicationConfigWrapper applicationConfigWrapper){
        ApplicationConfigWrapper result=new ApplicationConfigWrapper();
        result.setApplicationName(applicationName);
        //1:组装ApiDataList
        List<ApplicationConfig.ApiData> apiDataList = applicationConfigWrapper.getApiDataListList();
        if(!apiDataList.isEmpty()){
            for (ApplicationConfig.ApiData apiData : apiDataList) {
                ApiData newApiData=new ApiData();
                newApiData.setApplicationName(applicationName);
                newApiData.setInterfaceName(apiData.getInterfaceName());
                newApiData.setTimeout(apiData.getTimeout());
                newApiData.setAsync(apiData.getIsAsync());
                newApiData.setRpcRegistryAddress(apiData.getRpcRegistryAddress());
                //2:组装一个ApiData的方法列表
                List<ApplicationConfig.MethodData> methodDataList = apiData.getMethodDataListList();
                if(!methodDataList.isEmpty()){
                    for (ApplicationConfig.MethodData methodData : methodDataList) {
                        MethodData newMethodData=new MethodData();
                        newMethodData.setMethodName(methodData.getMethodName());
                        newMethodData.setAuth(methodData.getIsAuth());
                        newMethodData.setUri(methodData.getUri());
                        newMethodData.setParameterTypeName(methodData.getParameterTypeName());

                        newApiData.addMethodData(newMethodData);
                    }
                }
                result.addApiData(newApiData);
            }
        }
        //3：组装DataVersion
        ApplicationConfig.DataVersion dataVersion = applicationConfigWrapper.getDataVersion();
        result.setDataVersion(new DataVersion(dataVersion.getTimestamp(),dataVersion.getDataVersion()));
        return result;
    }
}
